package com.zz.ecommerce.interceptor;

import com.sdeport.common.vo.OrganizationJobVO;
import com.sdeport.common.vo.OrganizationVO;
import com.sdeport.common.vo.UserVO;
import com.sdeport.security.shiro.SDUtils;
import com.zz.ecommerce.user.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

/**
 * 用户权限、url校验拦截器
 *
 * @author
 */
public class AuthorityInterceptor implements HandlerInterceptor {

    private static final String USER_INFO = "UserInfo";
    private final Logger logger = LoggerFactory.getLogger(AuthorityInterceptor.class);

    private String basePath;

    private String excludedUrls;
    private String needAuthUrls;

    /**
     * URL校验
     * 1、如果为js、css、img或越权页面，直接通过
     * 2、如果为需要鉴权的URL，则进行鉴权操作
     * 3、如果是普通的URL，则取session，如果session里的operId不为空，则通过
     * 4、其他情况均跳转到越权页面
     *
     * @throws Exception
     */
    @Override
    public boolean preHandle(
        HttpServletRequest request, HttpServletResponse response, Object handler) {

        String requestURI = request.getRequestURI();
        //        logger.debug("requestURI={}", requestURI);
        char chr = '/';
        if (requestURI.indexOf(chr) == requestURI.lastIndexOf(chr)) {
            requestURI += "/";
            //            logger.debug("update requestURI={}", requestURI);
        }

        basePath = requestURI.substring(0, requestURI.substring(1).indexOf("/") + 2);

        //        logger.debug("basePath={}", basePath);

        /**
         * 应用的根路径不进行鉴权验证
         */
        if (basePath.equals(requestURI)) {
            return true;
        }

        boolean bValidResult = false;
        try {
            HttpSession session = request.getSession();
            if (isExcludeUrl(requestURI)) {
                bValidResult = true;
            } else {
                //                logger.debug("servletPath={}", requestURI);
                bValidResult = validAuth(session);
                //                logger.debug("bValidResult={}", bValidResult);
                if (!bValidResult) {
                    try {
                        Session casSession = SecurityUtils.getSubject().getSession();
                        casSession.removeAttribute("current_user");
                    } catch (Exception e) {
                        logger.error("", e);
                    } finally {
                        response.sendRedirect(basePath + "index.jsp");
                        return false;
                    }

                }
            }
        } catch (Exception e) {
            logger.error("valid url Exception ", e);
            return false;
        }

        return bValidResult;
    }

    @Override
    public void postHandle(
        HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        //暂不实现
    }

    @Override
    public void afterCompletion(
        HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //暂不实现
    }

    /**
     * 校验URL是否是不需要鉴权的URL
     */
    private boolean isExcludeUrl(String servletPath) {
        String[] urls = excludedUrls.split(",");
        for (String excludedUrl : urls) {
            if (servletPath.indexOf(excludedUrl) != -1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否是需要鉴权的URL
     */
    private boolean isNeedAuthUrl(String servletPath) {
        String[] urls = needAuthUrls.split(",");
        for (String needAuthUrl : urls) {
            if (servletPath.indexOf(needAuthUrl) != -1) {
                return true;
            }
        }
        return false;
    }


    private boolean existsOperInfoInSession(HttpSession session) {
        UserInfo userInfo = (UserInfo) session.getAttribute(USER_INFO);
        //        logger.debug("userInfo={}", userInfo);
        try {
            if (null == userInfo) {
                UserVO userVO = SDUtils.getCurrentUser();
                //                logger.debug("userVO={}", userVO);
                if (userVO != null) {
                    userInfo = setSessionUserInfo(session, userVO);
                } else {
                    return false;
                }
            }
        } catch (Exception e) {
            logger.error("", e);
            return false;
        }
        //        logger.debug("===userInfo={}", userInfo);
        return StringUtils.isNotBlank(null == userInfo ? "" : userInfo.getLogName());
    }

    /**
     * 重新放置session 并返回用户信息
     *
     * @param session
     * @param userVO
     * @return
     */
    private UserInfo setSessionUserInfo(final HttpSession session, final UserVO userVO) {
        final UserInfo userInfo = new UserInfo();
        String username = userVO.getUsername();
        String departmentId = userVO.getDepartmentId();
        String companyId = userVO.getCompanyId();
        String companyName = userVO.getCompanyName();
        String cnName = userVO.getCnName();

        if (StringUtils.isNotEmpty(username)) {
            userInfo.setLogName(username);
            userInfo.setName(username);
        }
        if (StringUtils.isNotEmpty(departmentId)) {
            userInfo.setDepartmentId(departmentId);
        }

        List<OrganizationJobVO> jobList = userVO.getOrganizationJobs();
        if (!CollectionUtils.isEmpty(jobList)) {
            OrganizationVO organization = jobList.get(0).getOrganization();
            if (null != organization) {
                userInfo.setOrganizationId(organization.getOrganizationCode());
            }
        }
        if (StringUtils.isNotEmpty(companyId)) {
            userInfo.setCompanyId(companyId);
        }
        if (StringUtils.isNotEmpty(companyName)) {
            userInfo.setCompany(companyName);
        }
        if (StringUtils.isNotEmpty(cnName)) {
            userInfo.setName(cnName);
        }
        session.setAttribute(USER_INFO, userInfo);
        return userInfo;
    }

    /**
     * 判断当前oper是否有权限访问
     *
     * @throws IOException
     */

    private boolean validAuth(HttpSession session) throws IOException {
        if (existsOperInfoInSession(session)) {
            return true;
        }
        return false;
    }

    public void setExcludedUrls(String excludedUrls) {
        this.excludedUrls = excludedUrls;
    }

    public void setNeedAuthUrls(String needAuthUrls) {
        this.needAuthUrls = needAuthUrls;
    }
}
